package com.leyou.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leyou.common.dto.PageDTO;
import com.leyou.common.exception.LyException;
import com.leyou.dto.CategoryDTO;
import com.leyou.dto.SkuDTO;
import com.leyou.dto.SpuDTO;
import com.leyou.dto.SpuDetailDTO;
import com.leyou.entity.*;
import com.leyou.mapper.SpuMapper;
import com.leyou.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class SpuServiceImpl extends ServiceImpl<SpuMapper, Spu>implements SpuService {


    @Autowired
    private CategoryService categoryService;

    @Autowired
    private BrandService brandService;
    @Autowired
    private SpuService spuService;
    @Autowired
    private SkuService skuService;
    @Autowired
    private SpuDetailService spuDetailService;


    /*
    * TODO 商品分页查询
    *  */
    @Override
    public PageDTO<SpuDTO> querySpuByPage(Long id, Long brandId, Long categoryId, Integer page, Integer rows, Boolean saleable) {
        Page<Spu> iPage = new Page<>(page, rows);
        //加强代码健壮性
        int current=Math.max(page,1);
        int size=Math.max(rows,5);
        //todo 分页查询
        page(iPage,new QueryWrapper<Spu>().eq(id!=null,"id",id)
                  .eq(brandId!=null,"brand_id",brandId)
                  .eq(categoryId!=null,"cid3",categoryId)
                  .eq(saleable!=null,"saleable",saleable)
        );
        //todo 类型转换
        List<SpuDTO> spuDTOS = SpuDTO.convertEntityList(iPage.getRecords());
         spuDTOS.forEach(spuDTO -> {
             //todo 根据品牌id查询对应的品牌对象，并获取名称
             spuDTO.setBrandName(this.brandService.queryBrandById(spuDTO.getBrandId()).getName());
         //todo 根据分类的id集合查询分类集合，并且获得分类名称，已分隔符分割各个分类名称
             String categoryNames=this.categoryService.listCategoryByIds(spuDTO.getCategoryIds())
                     .stream()
                     .map(CategoryDTO::getName)
                     .collect(Collectors.joining("/"));
             spuDTO.setCategoryName(categoryNames);
         });
         return new PageDTO<>(iPage.getTotal(),iPage.getPages(),spuDTOS);

    }

    /*
    * todo 根据Id查询商品Spu
    *  */
    @Override
    public SpuDTO querySpuById(Long id) {
        return new SpuDTO(this.getById(id));
    }



    //todo 商品新增
    @Override
    @Transactional
    public void saveGoods(SpuDTO spuDTO) {
        Spu spu = spuDTO.toEntity(Spu.class);
        //保存spu，并主键回显
        this.spuService.save(spu);
        SpuDetail spuDetail = spuDTO.getSpuDetailDTO().toEntity(SpuDetail.class);
        spuDetail.setSpuId(spu.getId());
        //保存spuDetail
        this.spuDetailService.save(spuDetail);
        //spu中取出skuDTO集合，转换成sku得集合并依次给每一个sku对象设置对应得spuId
        List<Sku> skus=spuDTO.getSkus().stream().map(skuDTO -> {Sku sku=skuDTO.toEntity(Sku.class);
        sku.setSpuId(spu.getId());
        return sku;
        }).collect(Collectors.toList());
        this.skuService.saveBatch(skus);
    }

    // todo 商品上下架
    @Override
    @Transactional
    public void updateSpuSaleable(Long spuId,Boolean saleable) {
        //更新spu
        Spu spu = new Spu();
        spu.setId(spuId);
        spu.setSaleable(saleable);
        boolean success = this.spuService.updateById(spu);
        //更新判断
        if (!success){
            throw new LyException(500,"更新失败");
        }
        //更新sku
        Sku sku = new Sku();
        sku.setSaleable(saleable);
         boolean success1 = this.skuService.update()
                 .eq("spu_id", spuId)
                 .set("saleable", saleable).update();
         if (!success1){
             throw new LyException(500,"更新失败");
         }
    }

    //todo 商品修改
    @Override
    @Transactional
    public void updateGoods(SpuDTO spuDTO) {
        //1\修改spu
        //判断是否存在得spu得id，有说明得需要改动，没有说明得不需要
        if (spuDTO.getId()!=null){
            //spu需要修改，更新spu
            boolean success1 = this.spuService.updateById(spuDTO.toEntity(Spu.class));
            if (!success1){
                throw  new LyException(500,"更新失败");
            }
        }
        //todo 2\修改spuDetail
        SpuDetailDTO detailDTO = spuDTO.getSpuDetailDTO();
        if (detailDTO!=null&&detailDTO.getSpuId()!=null){
            boolean success2 = this.spuDetailService.updateById(detailDTO.toEntity(SpuDetail.class));
            if (!success2){
                throw new LyException(500, "更新商品失败！");
            }
        }

 /*
 todo 修改sku
         修改sku有三种可能,新增、删除、修改
 */
        List<SkuDTO> dtoList = spuDTO.getSkus();
        //判断是否包含sku
        if (!CollectionUtils.isEmpty(dtoList)){
            ArrayList<Sku> toADD = new ArrayList<>();
            ArrayList<Sku> toDelete = new ArrayList<>();
            ArrayList<Sku> toUpdate = new ArrayList<>();
            //遍历传来得sku集合，分离
            spuDTO.getSkus().forEach(skuDTO -> {
                Sku sku = skuDTO.toEntity(Sku.class);
                //没有id，表示要新增
                if (sku.getId()==null){
                    toADD.add(sku);
                    //saleable为空表示要修改
                }else if (sku.getSaleable()==null){
                    toUpdate.add(sku);
                    //saleable不为空，表示要删除
                }else {
                    toDelete.add(sku);
                }
            });
            if (!CollectionUtils.isEmpty(toADD)) {
                this.skuService.saveBatch(toADD);
            }
            if (!CollectionUtils.isEmpty(toDelete)) {
                this.skuService.removeByIds(toDelete.stream().map(Sku::getId).collect(Collectors.toList()));
            }
            if (!CollectionUtils.isEmpty(toUpdate)) {
                this.skuService.updateBatchById(toUpdate);
            }
        }
    }
}
